#pragma once

#include <map>
#include <memory>
#include <string>
#include <zmqpp/zmqpp.hpp>
#include "base/Bytes.h"
#include "base/Logger.h"
 

namespace zeroplus::mq
{

    class ZmqConnection
    {
    private:
        uint64_t totalMsgWritten_;
        uint64_t totalMsgRead_;
        uint64_t totalBytesWritten_;
        uint64_t totalBytesRead_;
        zmqpp::context_t context_;
        std::unique_ptr<zmqpp::socket_t> socket_;
        std::string uri_;

    public:
        ZmqConnection(const zmqpp::socket_type &type, std::string uri)
            : totalMsgWritten_(0),
              totalMsgRead_(0),
              totalBytesWritten_(0),
              totalBytesRead_(0),
              uri_(uri)
        {
            socket_ = std::make_unique<zmqpp::socket_t>(context_, type);
        }

        virtual ~ZmqConnection()
        {
        }

        void Bind();

        void UnBind();

        void Connect();

        void DisConnect();

        ssize_t WriteMsg(zmqpp::message_t &message, int sendFlag = zmqpp::socket::normal);

        std::tuple<zmqpp::message_t, bool> ReadMsg();

        size_t Size(const zmqpp::message_t &message)
        {
            size_t size = 0;
            for (int i = 0; i < message.parts(); i++)
            {
                size += message.size(i);
            }
            return size;
        }

        zmqpp::socket_t *GetSocket()
        {
            return socket_.get();
        }

        void SetSubscribe(const std::string &buf)
        {
            socket_->subscribe(buf.c_str());
        }

        void SetSendTimeout(const int &timeout)
        {
            socket_->set(zmqpp::socket_option::send_timeout, timeout);
        }

        void SetRecvTimeout(const int &timeout)
        {
            socket_->set(zmqpp::socket_option::receive_timeout, timeout / 1000);
        }

        int GetKernelBufferSize()
        {
            // 获取内核接收缓冲区大小
            socket_->set(zmqpp::socket_option::send_buffer_size, 1000);
            int recvBufSize = 0;
            socket_->get(zmqpp::socket_option::receive_buffer_size, recvBufSize);
            return recvBufSize;
        }
    };

}
